# /**
# * Copyright (c) 2022 Beijing Jiaotong University
# * PhotLab is licensed under [Open Source License].
# * You can use this software according to the terms and conditions of the [Open Source License].
# *
# * You may obtain a copy of [Open Source License] at: [https://open.source.license/]
# *
# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# *
# * See the [Open Source License] for more details.
# */
# /**
# * Author: Shihao Xie
# * Created: Mar. 24, 2023
# * Supported by: National Key Research and Development Program of China
# */

from phot_server.core.api_injector import api
from phot_server.manager.grid_manager import GridManager
from phot_server.rpc.device_service.Device import Processor


class GridService:
    """
    该服务是器件仿真相关服务，可以通过这个服务管理用户拥有的仿真网格。
    调用该服务前，请确认已经做过连接服务相关操作并成功连接。例如：

    Examples:
        >>> from thrift import Thrift
        >>> from thrift.transport import TSocket
        >>> from thrift.transport import TTransport
        >>> from thrift.protocol import TBinaryProtocol
        >>> from photlab.device_service.Device import Client as grid_client
        >>> transport = TSocket.TSocket("localhost", 8080)
        >>> transport_protocol = TTransport.TBufferedTransport(transport)
        >>> protocol_factory = TBinaryProtocol.TBinaryProtocol(transport_protocol)
        >>> grid_client = grid_client(protocol_factory)
        >>> transport.open()

    具体使用可以查看测试用例 test/test_interface/test_fdtd.py

    注意：目前还没确定grid的文件格式和形式化描述方法，所以还没有grid文件读取和保存的接口。
    """

    # 注意：以下接口操作的仿真网格(PhotGrid)是经过接口open_grid打开和加载后的数据对象。
    def __init__(self):
        self.grid_manager = GridManager()

    @api(Processor.process_open_grid)
    def open_grid(self, grid_path):
        """
        服务端打开一个仿真网格文件，加载仿真网格的数据并生成一个仿真网格模型(PhotGrid)。

        Args:
            grid_path (string): 仿真网格的路径

        Returns:
            PhotGrid: 仿真网格模型

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.open_grid("C://user//grid_1.phtg")
        """
        return self.grid_manager.open_grid(grid_path)

    @api(Processor.process_close_grid)
    def close_grid(self, grid_id):
        """
        服务端关闭一个已打开的仿真网格。

        Args:
            grid_id (long): 仿真网格的ID

        Returns:

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.close_grid(11111111)
        """
        return self.grid_manager.close_grid(grid_id)

    @api(Processor.process_save_grid)
    def save_grid(self, grid_id):
        """
        服务端保存一个仿真网格模型(PhotGrid)到它的源文件。

        Args:
            grid_id (long): 仿真网格的ID

        Returns:

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.save_grid(11111111)
        """
        self.grid_manager.save_grid(grid_id)

    @api(Processor.process_save_grid_as)
    def save_grid_as(self, grid_id, file_path):
        """
        服务端保存一个仿真网格模型(PhotGrid)到指定的文件。

        Args:
            grid_id (long): 仿真网格的ID

        Returns:

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.save_grid_as(1111111, "C://user//graph_1.phtg")
        """
        self.grid_manager.save_grid_as(grid_id, file_path)

    @api(Processor.process_get_opened_grid_list)
    def get_opened_grid_list(self):
        """
        获取所有已经打开的仿真区域。

        Args:

        Returns:
            map<string, string>: 返回一个包含<gridId, gridName>的字典

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.get_opened_grid_list()

        """
        return self.grid_manager.get_opened_grid_list()

    @api(Processor.process_add_grid)
    def add_grid(self, grid):
        """
        向服务端添加一个仿真网格(PhotGrid)。

        Args:
            grid (PhotGrid): 仿真网格

        Returns:
            PhotGrid: 仿真网格

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid = PhotGrid(gridId=0,
                                xLength=200,
                                yLength=200,
                                zLength=10,
                                gridSpacing=155e-9,
                                totalTime=100,
                                pmlWidth=5)
            >>> grid_client.add_grid(grid)
        """
        return self.grid_manager.add_grid(grid)

    @api(Processor.process_add_source)
    def add_source(self, grid_id, source):
        """
        向仿真网格添加一个光源。

        Args:
            grid_id (int): 网格id
            source (PhotSource): 光源

        Returns:
            PhotSource: 光源

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> source = PhotSource(lightSourceId=1,
                                               name="Source_1",
                                               sourceType="linesource",
                                               x=16,
                                               xLength=0,
                                               y=19,
                                               yLength=7,
                                               period=1550e-9 / 299792458)
            >>> grid_client.add_source(0, source)
        """
        return self.grid_manager.add_source(grid_id, source)

    @api(Processor.process_add_waveguide)
    def add_waveguide(self, grid_id, waveguide):
        """
        向仿真网格添加一个波导。

        Args:
            grid_id (int): 网格id
            waveguide (PhotWaveguide): 波导

        Returns:
            PhotWaveguide: 波导

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> waveguide_1 = PhotWaveguide(waveguideId=2,
                                            zLength=1,
                                            x=20,
                                            y=20,
                                            z=1,
                                            width=4,
                                            refractiveIndex=3.47,
                                            className="Ring",
                                            name="ring_1",
                                            extraParameters={"direction": 1,
                                                             "outer_radius": 40,
                                                             "gap": 1,
                                                             "length": 0})
            >>> grid_client.add_waveguide(0, waveguide_1)
        """
        return self.grid_manager.add_waveguide(grid_id, waveguide)

    @api(Processor.process_add_material)
    def add_material(self, material):
        """
        向材料库添加一个材料。

        Args:
            material (PhotMaterial): 材料

        Returns:
            PhotMaterial: 材料

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> material = PhotMaterial()
            >>> grid_client.add_material(material)
        """
        return self.grid_manager.add_material(material)

    @api(Processor.process_add_detector)
    def add_detector(self, grid_id, detector):
        """
        向仿真网格添加一个探测器。

        Args:
            grid_id (int): 网格id
            detector (PhotDetector): 探测器

        Returns:
            PhotDetector: 探测器

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> detector = PhotDetector(detectorId = 3)
            >>> grid_client.add_detector(0, detector)
        """
        return self.grid_manager.add_detector(grid_id, detector)

    # Get services
    @api(Processor.process_get_grid)
    def get_grid(self, grid_id):
        """
        获取一个仿真网格。

        Args:
            grid_id (int): 网格id

        Returns:
            PhotGrid: 仿真网格

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.get_grid(0)
        """
        return self.grid_manager.get_grid(grid_id)

    @api(Processor.process_get_source)
    def get_source(self, grid_id, source_id):
        """
        从仿真网格中获取一个已有光源。

        Args:
            grid_id (int): 网格id
            source_id (int): 光源id

        Returns:
            PhotSource: 光源

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.get_source(0, 1)
        """
        return self.grid_manager.get_source(grid_id, source_id)

    @api(Processor.process_get_waveguide)
    def get_waveguide(self, grid_id, waveguide_id):
        """
        从仿真网格中获取一个已有波导。

        Args:
            grid_id (int): 网格id
            waveguide_id (int): 波导id

        Returns:
            PhotWaveguide: 波导

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.get_waveguide(0, 2)
        """
        return self.grid_manager.get_waveguide(grid_id, waveguide_id)

    @api(Processor.process_get_material)
    def get_material(self, material_name):
        """
        从材料库中获取一个材料。

        Args:
            material_name (string): 材料名称

        Returns:
            PhotMaterial: 材料

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.get_material("Au")
        """
        return self.grid_manager.get_material(material_name)

    @api(Processor.process_get_materials)
    def get_materials(self):
        """
        从材料库中获取材料列表。

        Args:
            无

        Returns:
            list<PhotMaterial>: 材料列表

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.get_materials()
        """
        return self.grid_manager.get_all_materials()

    @api(Processor.process_get_material_name_list)
    def get_material_name_list(self):
        """
        从材料库中获取材料名称列表。

        Args:
            无

        Returns:
            list<string>: 材料名称列表

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.get_materials()
        """
        return self.grid_manager.get_material_name_list()

    @api(Processor.process_get_detector)
    def get_detector(self, grid_id, detector_id):
        """
        从仿真网格中获取一个已有探测器。

        Args:
            grid_id (int): 网格id
            detector_id (int): 探测器id

        Returns:
            PhotDetector: 探测器

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.get_detector(0, 3)
        """
        return self.grid_manager.get_detector(grid_id, detector_id)

    @api(Processor.process_get_figure)
    def get_figure(self, grid_id, axis, axis_index, figure_type):
        """
        从仿真网格中获取一个视图。

        Args:
            grid_id (int): 网格id
            axis (string): 视图方向
            axis_index (int): 切片坐标
            figure_type (string): 视图类型，剖面图(Sectional View)或 折射率图(Refractive Index View)

        Returns:
            PhotFigure: 仿真网格视图

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> # Assume: Grid(xLength = 100, yLength = 100, zLength = 100, ...),
            >>> #         Waveguide(x=50, y=50, z=50, xLength = 10, yLength = 10, zLength = 10, ...)
            >>> #         Waveguide(x=60, y=50, z=50, xLength = 10, yLength = 10, zLength = 10, ...)
            >>>
            >>> # Usage 1:  figure_type = "Sectional View"
            >>> grid_client.get_figure(grid_id = 0, axis = "x", axis_index = 0, figure_type = "Sectional View")
            >>> PhotFigure(name="Grid_0_Sectional_View", axis="x", axis_index=0, type="Sectional View",
            >>>            path="${TEMP_ROOT}/Grid_0_Sectional_View_x_0.png", figure=b'...')
            >>>
            >>> # Usage 2:  figure_type = "Refractive Index View"
            >>> grid_client.get_figure(grid_id = 0, axis = "x", axis_index = 0, figure_type = "Refractive Index View")
            >>> PhotFigure(name="Grid_0_Refractive_Index_View", axis="x", axis_index=0, type="Refractive Index View",
            >>>            path="${TEMP_ROOT}/Grid_0_Refractive_Index_View_x_1.png", figure=b'...')
            >>>
            >>> # Usage 3: When axis index == -1, server would choose the mean of waveguide axis index as the figure axis index.
            >>> grid_client.get_figure(grid_id = 0, axis = "x", axis_index = -1, figure_type = "Sectional View")
            >>> PhotFigure(name="Grid_0_Sectional_View", axis="x", axis_index=55, type="Sectional View",
            >>>            path="${TEMP_ROOT}/Grid_0_Sectional_View_x_2.png", figure=b'...')
        """
        return self.grid_manager.get_figure(grid_id, axis, axis_index, figure_type)

    @api(Processor.process_get_figures)
    def get_figures(self, grid_id, axis_index, figure_type):
        """
        获取一个仿真网格的三视图。在获取视图之前先对仿真网格进行计算(run)。

        Args:
            grid_id (int): 网格id
            axis_index (list<int>): 切片坐标
            figure_type(string): 视图类型，剖面图(Sectional View)或 折射率图(Refractive Index View)

        Returns:
            list<PhotFigure>: 仿真网格视图列表

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> # Assume: Grid(xLength = 100, yLength = 100, zLength = 100, ...),
            >>> #         Waveguide(x=50, y=50, z=50, xLength = 10, yLength = 10, zLength = 10, ...)
            >>> #         Waveguide(x=60, y=50, z=50, xLength = 10, yLength = 10, zLength = 10, ...)
            >>>
            >>> # Usage 1:  figure_type = "Sectional View"
            >>> grid_client.get_figures(grid_id = 0, axis_index = [0,0,0], figure_type = "Sectional View")
            >>> { "x" : PhotFigure(name="Grid_0_Sectional_View", axis="x", axis_index=0, type="Sectional View",
            >>>                    path="${TEMP_ROOT}/Grid_0_Sectional_View_x_0.png", figure=b'...'),
            >>>   "y" : PhotFigure(name="Grid_0_Sectional_View", axis="y", axis_index=0, type="Sectional View",
            >>>                    path="${TEMP_ROOT}/Grid_0_Sectional_View_y_1.png", figure=b'...'),
            >>>   "z" : PhotFigure(name="Grid_0_Sectional_View", axis="z", axis_index=0, type="Sectional View",
            >>>                    path="${TEMP_ROOT}/Grid_0_Sectional_View_z_2.png", figure=b'...'),
            >>> }
            >>>
            >>> # Usage 2:  figure_type = "Refractive Index View"
            >>> grid_client.get_figures(grid_id = 0, axis_index = [50,50,50], figure_type = "Refractive Index View")
            >>> { "Refractive_Index_View_x" : PhotFigure(name="Grid_0_Refractive_Index_View", axis="x", axis_index=50, type="Refractive Index View",
            >>>                    path="${TEMP_ROOT}/Grid_0_Sectional_View_x_3.png", figure=b'...'),
            >>>   "Refractive_Index_View_y" : PhotFigure(name="Grid_0_Refractive_Index_View", axis="y", axis_index=50, type="Refractive Index View",
            >>>                    path="${TEMP_ROOT}/Grid_0_Sectional_View_y_4.png", figure=b'...'),
            >>>   "Refractive_Index_View_z" : PhotFigure(name="Grid_0_Refractive_Index_View", axis="z", axis_index=50, type="Refractive Index View",
            >>>                    path="${TEMP_ROOT}/Grid_0_Refractive_Index_View_z_5.png", figure=b'...'),
            >>> }
            >>>
            >>> # Usage 3: When one of axis index == -1, server would choose the mean of waveguide axis index as the figure axis index.
            >>> #          When figure_type == "", server would return figures of type "Sectional View" and "Refractive Index View"
            >>> grid_client.get_figures(grid_id = 0, axis_index = [-1,40,-1], figure_type = "")
            >>> { "x" : PhotFigure(name="Grid_0_Sectional_View", axis="x", axis_index=55, type="Sectional View",
            >>>                    path="${TEMP_ROOT}/Grid_0_Sectional_View_x_6.png", figure=b'...'),
            >>>   "y" : PhotFigure(name="Grid_0_Sectional_View", axis="y", axis_index=40, type="Sectional View",
            >>>                    path="${TEMP_ROOT}/Grid_0_Sectional_View_y_7.png", figure=b'...'),
            >>>   "z" : PhotFigure(name="Grid_0_Sectional_View", axis="z", axis_index=50, type="Sectional View",
            >>>                    path="${TEMP_ROOT}/Grid_0_Sectional_View_z_8.png", figure=b'...'),
            >>>   "Refractive_Index_View_x" : PhotFigure(name="Grid_0_Refractive_Index_View", axis="x", axis_index=55, type="Refractive Index View",
            >>>                    path="${TEMP_ROOT}/Grid_0_Sectional_View_x_9.png", figure=b'...'),
            >>>   "Refractive_Index_View_y" : PhotFigure(name="Grid_0_Refractive_Index_View", axis="y", axis_index=40, type="Refractive Index View",
            >>>                    path="${TEMP_ROOT}/Grid_0_Sectional_View_y_10.png", figure=b'...'),
            >>>   "Refractive_Index_View_z" : PhotFigure(name="Grid_0_Refractive_Index_View", axis="z", axis_index=50, type="Refractive Index View",
            >>>                    path="${TEMP_ROOT}/Grid_0_Refractive_Index_View_z_11.png", figure=b'...'),
            >>> }
        """
        return self.grid_manager.get_figures(grid_id, axis_index, figure_type)

    @api(Processor.process_get_waveguide_default_parameter_list)
    def get_waveguide_default_parameter_list(self, name):
        """
        获取波导默认参数列表。

        Args:
            name (string): 波导名称

        Returns:
            string: json

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.get_waveguide_parameter_list("Waveguide")
        """
        return self.grid_manager.get_waveguide_parameter_list(name)

    @api(Processor.process_get_all_waveguide_default_parameter_list)
    def get_all_waveguide_default_parameter_list(self):
        """
        获取波导默认参数列表。

        Args:

        Returns:
            string: json

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.get_all_waveguide_parameter_list()
        """
        return self.grid_manager.get_all_waveguide_parameter_list()

    # update service
    @api(Processor.process_update_grid)
    def update_grid(self, grid):
        """
        更新一个仿真网格。

        Args:
            grid (PhotGrid): 仿真网格

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid = PhotGrid(gridId=0,
                                xLength=100,
                                yLength=100,
                                zLength=10,
                                gridSpacing=155e-9,
                                totalTime=100,
                                pmlWidth=5)
            >>> grid_client.update_grid(grid)
        """
        self.grid_manager.set_grid(grid)

    @api(Processor.process_update_source)
    def update_source(self, grid_id, source):
        """
        更新一个仿真网格里的一个光源。

        Args:
            grid_id (int): 网格id
            source (PhotSource): 光源

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> source = PhotSource(lightSourceId=1,
                                               name="Source_1",
                                               sourceType="linesource",
                                               x=10,
                                               xLength=5,
                                               y=10,
                                               yLength=5,
                                               period=1550e-9 / 299792458)
            >>> grid_client.update_source(0, source)
        """
        self.grid_manager.update_source_attrs(grid_id, source)

    @api(Processor.process_update_waveguide)
    def update_waveguide(self, grid_id, waveguide):
        """
        更新一个仿真网格里的一个波导。

        Args:
            grid_id (int): 网格id
            waveguide (PhotWaveguide): 波导

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> waveguide = PhotWaveguide(waveguideId=2,
                                          zLength=1,
                                          x=10,
                                          y=10,
                                          z=1,
                                          width=4,
                                          refractiveIndex=3.47,
                                          className="Ring",
                                          name="ring_1",
                                          extraParameters={"direction": 1,
                                                           "outer_radius": 40,
                                                           "gap": 1,
                                                           "length": 0})
            >>> grid_client.update_waveguide(0, waveguide_1)
        """
        self.grid_manager.update_waveguide_attrs(grid_id, waveguide)

    @api(Processor.process_update_material)
    def update_material(self, material):
        """
        更新一个材料。

        Args:
            material_name (string): 材料名称
            material (PhotMaterial): 材料

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> material = PhotMaterial(name="Au",color = "#FFD700",properties=[PhotMaterialProperty(propertyId=1)])
            >>> grid_client.update_material("Au", material)
        """
        self.grid_manager.update_material(material)

    @api(Processor.process_update_material_property)
    def update_material_property(self, material_name, material_property):
        """
        更新一个材料的一个属性。

        Args:
            material_name (string): 材料名称
            material_property (PhotMaterialProperty): 材料属性

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.update_source(0, PhotMaterialProperty(propertyId = 1,waveLength = 0.0175,real = 0.8888,imag = 0.0703))
        """
        self.grid_manager.update_material_property(material_name, material_property)

    @api(Processor.process_update_detector)
    def update_detector(self, grid_id, detector):
        """
        更新一个仿真网格里的一个探测器。

        Args:
            grid_id (int): 网格id
            detector (PhotDetector): 探测器

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.update_detector(0, PhotDetector(detectorId=3))
        """
        self.grid_manager.update_detector_attrs(grid_id, detector)

    # delete service

    @api(Processor.process_delete_grid)
    def delete_grid(self, grid_id):
        """
        删除一个仿真网格。

        Args:
            grid_id (int): 网格id

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.delete_grid(0)
        """
        self.grid_manager.delete_grid(grid_id)

    @api(Processor.process_delete_source)
    def delete_source(self, grid_id, source_id):
        """
        删除仿真网格中的一个光源。

        Args:
            grid_id (int): 网格id
            source_id (int): 光源id

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.delete_source(0, 1)
        """
        self.grid_manager.delete_source(grid_id, source_id)

    @api(Processor.process_delete_waveguide)
    def delete_waveguide(self, grid_id, waveguide_id):
        """
        删除仿真网格中的一个波导。

        Args:
            grid_id (int): 网格id
            waveguide_id (int): 波导id

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.delete_waveguide(0, 2)
        """
        self.grid_manager.delete_waveguide(grid_id, waveguide_id)

    @api(Processor.process_delete_material)
    def delete_material(self, material_name):
        """
        删除一个材料。

        Args:
            material_name (string): 材料名称

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.delete_material("Au")
        """
        self.grid_manager.delete_material(material_name)

    @api(Processor.process_delete_material_property)
    def delete_material_property(self, material_name, property_id):
        """
        删除一个材料属性。

        Args:
            material_name (string): 材料名称
            property_id (int): 属性id

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.delete_material_property("Au", 1)
        """
        self.grid_manager.delete_material_property(material_name, property_id)

    @api(Processor.process_delete_detector)
    def delete_detector(self, grid_id, detector_id):
        """
        删除仿真网格中的一个探测器。

        Args:
            grid_id (int): 网格id
            detector_id (int): 光源id

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.delete_detector(0, 3)
        """
        self.grid_manager.delete_detector(grid_id, detector_id)

    # save service
    #
    @api(Processor.process_save_material_as)
    def save_material_as(self, material_name, file_path):
        """
        将已有的材料数据保存到本地文件。

        Args:
            material_name: 材料名称
            file_path: 材料数据的保存路径

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.open_graph("C://user//graph_1.phtg")
        """
        self.grid_manager.save_material_as(material_name, file_path)

    @api(Processor.process_save_figure_as)
    def save_figure_as(self, grid_id, axis: str, axis_index: list, file_path, figure_type):
        """
        将仿真网格三视图另存为其他文件。目前只支持png格式。

        Args:
            grid_id (int): 网格id
            axis (string): 视图方向
            axis_index (int): 切片坐标
            file_path (string): 文件路径，包含文件后缀
            figure_type(string): 视图类型，剖面图(Sectional View)或 折射率图(Refractive Index View)

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> # Assume: Grid(xLength = 100, yLength = 100, zLength = 100, ...),
            >>> #         Waveguide(x=50, y=50, z=50, xLength = 10, yLength = 10, zLength = 10, ...)
            >>> #         Waveguide(x=60, y=50, z=50, xLength = 10, yLength = 10, zLength = 10, ...)
            >>>
            >>> # Usage 1:  save a figure of one axis
            >>> grid_client.save_figure_as(grid_id=0, axis="x", axis_index=[0], file_path="C://grid_0.png",
            >>>                            figure_type="Sectional View" || "Refractive Index View")
            >>> # figure save to "C://grid_0.png"
            >>>
            >>> # Usage 2:  save figures of all axis
            >>> grid_client.save_figure_as(grid_id=0, axis=None, axis_index=[-1,0,20], file_path="C://grid_0.png",
            >>>                            figure_type="Sectional View" || "Refractive Index View" || "")
            >>> # if figure_type=="Sectional View"
            >>> #   figure save to "C://grid_0_sectional_x_55.png"
            >>> #   figure save to "C://grid_0_sectional_y_0.png"
            >>> #   figure save to "C://grid_0_sectional_z_20.png"
            >>> # if figure_type=="Refractive Index View"
            >>> #   figure save to "C://grid_0_refractive_x_55.png"
            >>> #   figure save to "C://grid_0_refractive_y_0.png"
            >>> #   figure save to "C://grid_0_refractive_z_20.png"
            >>> # if figure_type==""
            >>> #   figure save to "C://grid_0_sectional_x_55.png"
            >>> #   figure save to "C://grid_0_sectional_y_0.png"
            >>> #   figure save to "C://grid_0_sectional_z_20.png"
            >>> #   figure save to "C://grid_0_refractive_x_55.png"
            >>> #   figure save to "C://grid_0_refractive_y_0.png"
            >>> #   figure save to "C://grid_0_refractive_z_20.png"
        """
        if axis is not None and len(axis_index) == 1:
            self.grid_manager.save_figure_as(grid_id, file_path, axis, axis_index[0], figure_type)
        elif axis is None and len(axis_index) == 3:
            self.grid_manager.save_figures_as(grid_id, file_path, ["x", "y", "z"], axis_index, figure_type)

    @api(Processor.process_get_grid_figure_history)
    def get_grid_figure_history(self, grid_id):
        """
        获取特定网格的三视图输出历史记录。

        Args:
            grid_id (int): 网格id

        Returns:
            list<string>

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.get_grid_figure_history(0)
            >>> ["C://user//Grid_12344567890_x_0.png",
            >>>  "C://user//Grid_12344567890_y_0.png",
            >>>  "C://user//Grid_12344567890_z_0.png"]
        """
        return self.grid_manager.get_grid_figure_history(grid_id)

    @api(Processor.process_run)
    def run(self, grid_id):
        """
        仿真计算一个仿真网格。

        Args:
            grid_id (int): 网格id

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> grid_client.run(0)
        """
        self.grid_manager.fdtd_simulation(grid_id)

    @api(Processor.process_calculate_mode)
    def calculate_mode(self, grid_id, axis="x", index=0, lam=1.55, neff=3.47, neigs=1, x_boundary_low="pml",
                       y_boundary_low="pml", x_thickness_low=0,
                       y_thickness_low=0, x_boundary_high="zero", y_boundary_high="zero", x_thickness_high=0,
                       y_thickness_high=0):
        return self.grid_manager.calculate_mode(grid_id, axis, index, lam, neff, neigs, x_boundary_low, y_boundary_low,
                                                x_thickness_low,
                                                y_thickness_low, x_boundary_high, y_boundary_high, x_thickness_high,
                                                y_thickness_high)

    @api(Processor.process_get_mode_figure)
    def get_mode_figure(self, grid_id, axis, axis_index, lam=1.55, neff=3.47, neigs=1):
        return self.grid_manager.get_mode_figure(grid_id, axis, axis_index, lam, neff, neigs)

    # @api(Processor.process_get_TEfraction_figure)
    # def get_TEfraction_figure(self, grid_id, n_levels=6):
    #     return self.grid_manager.get_TEfraction_figure(grid_id, n_levels)
    #
    # def sweep(self, grid_id, steps=5, lams=[]):
    #     self.grid_manager.sweep(grid_id, steps, lams)
